<!DOCTYPE html>
<html lang="" xml:lang="">
<head>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Chapter 5 Basic Widget | JavaScript for R</title>
  <meta name="description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="generator" content="bookdown 0.19 and GitBook 2.6.7" />

  <meta property="og:title" content="Chapter 5 Basic Widget | JavaScript for R" />
  <meta property="og:type" content="book" />
  
  
  <meta property="og:description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="github-repo" content="yihui/bookdown-crc" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="Chapter 5 Basic Widget | JavaScript for R" />
  
  <meta name="twitter:description" content="Invite JavaScript into your Data Science workflow." />
  

<meta name="author" content="John Coene" />


<meta name="date" content="2020-06-05" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  
  
<link rel="prev" href="a-two-way-street.html"/>
<link rel="next" href="external-library-1.html"/>
<script src="libs/header-attrs/header-attrs.js"></script>
<script src="libs/jquery/jquery.min.js"></script>
<link href="libs/gitbook/css/style.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-fontsettings.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-clipboard.css" rel="stylesheet" />









<script src="libs/htmlwidgets/htmlwidgets.js"></script>
<script src="libs/plotly-binding/plotly.js"></script>
<script src="libs/typedarray/typedarray.min.js"></script>
<link href="libs/crosstalk/css/crosstalk.css" rel="stylesheet" />
<script src="libs/crosstalk/js/crosstalk.min.js"></script>
<link href="libs/plotly-htmlwidgets-css/plotly-htmlwidgets.css" rel="stylesheet" />
<script src="libs/plotly-main/plotly-latest.min.js"></script>
<script src="libs/core-js/shim.min.js"></script>
<script src="libs/react/react.min.js"></script>
<script src="libs/react/react-dom.min.js"></script>
<script src="libs/reactwidget/react-tools.js"></script>
<script src="libs/reactable-binding/reactable.js"></script>
<script src="libs/r2d3-render/r2d3-render.js"></script>
<script src="libs/webcomponents/webcomponents.js"></script>
<script src="libs/r2d3-binding/r2d3.js"></script>
<script src="libs/d3v5/d3.min.js"></script>


<style type="text/css">
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {   }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>

<link rel="stylesheet" href="css/style.css" type="text/css" />
</head>

<body>



  <div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">

    <div class="book-summary">
      <nav role="navigation">

<ul class="summary">
<li><a href="./">R and JavaScript</a></li>

<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>Preface</a>
<ul>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#disclaimer"><i class="fa fa-check"></i>Disclaimer</a></li>
</ul></li>
<li class="part"><span><b>I Basics &amp; Roadmap</b></span></li>
<li class="chapter" data-level="1" data-path="introduction.html"><a href="introduction.html"><i class="fa fa-check"></i><b>1</b> Introduction</a>
<ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#rationale"><i class="fa fa-check"></i>Rationale</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#prerequisites"><i class="fa fa-check"></i>Prerequisites</a>
<ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#package-development"><i class="fa fa-check"></i>Package Development</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#json"><i class="fa fa-check"></i>JSON</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#javascript"><i class="fa fa-check"></i>JavaScript</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#methods"><i class="fa fa-check"></i>Methods</a>
<ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#v8"><i class="fa fa-check"></i>V8</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#htmlwidgets"><i class="fa fa-check"></i>htmlwidgets</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#shiny"><i class="fa fa-check"></i>Shiny</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#reactr"><i class="fa fa-check"></i>reactR</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#bubble"><i class="fa fa-check"></i>bubble</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#r2d3"><i class="fa fa-check"></i>r2d3</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>II JavaScript for Computations</b></span></li>
<li class="chapter" data-level="2" data-path="the-v8-engine.html"><a href="the-v8-engine.html"><i class="fa fa-check"></i><b>2</b> The V8 Engine</a>
<ul>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#installation"><i class="fa fa-check"></i>Installation</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#basics"><i class="fa fa-check"></i>Basics</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#external-libraries"><i class="fa fa-check"></i>External Libraries</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#with-npm"><i class="fa fa-check"></i>With Npm</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#use-in-packages"><i class="fa fa-check"></i>Use in Packages</a></li>
</ul></li>
<li class="chapter" data-level="3" data-path="node.html"><a href="node.html"><i class="fa fa-check"></i><b>3</b> Node.js with Bubble</a>
<ul>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#basics-1"><i class="fa fa-check"></i>Basics</a></li>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#r-markdown-engine"><i class="fa fa-check"></i>R Markdown Engine</a></li>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#npm"><i class="fa fa-check"></i>Npm</a></li>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#use-in-packages-1"><i class="fa fa-check"></i>Use in Packages</a></li>
</ul></li>
<li class="part"><span><b>III Web Development with Shiny</b></span></li>
<li class="chapter" data-level="4" data-path="a-two-way-street.html"><a href="a-two-way-street.html"><i class="fa fa-check"></i><b>4</b> A Two-way Street</a>
<ul>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#static-files"><i class="fa fa-check"></i>Static Files</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#integration"><i class="fa fa-check"></i>Integration</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#from-r-to-javascript"><i class="fa fa-check"></i>From R to JavaScript</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#from-javascript-to-r"><i class="fa fa-check"></i>From JavaScript to R</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#external-library"><i class="fa fa-check"></i>External Library</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#serialisation"><i class="fa fa-check"></i>Serialisation</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#events-callbacks"><i class="fa fa-check"></i>Events &amp; Callbacks</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#as-a-package"><i class="fa fa-check"></i>As a Package</a>
<ul>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#dependencies"><i class="fa fa-check"></i>Dependencies</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#r-code"><i class="fa fa-check"></i>R Code</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#javascript-code"><i class="fa fa-check"></i>JavaScript Code</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#shortcoming"><i class="fa fa-check"></i>Shortcoming</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#input"><i class="fa fa-check"></i>Input</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#wrapping-up"><i class="fa fa-check"></i>Wrapping up</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#exercises"><i class="fa fa-check"></i>Exercises</a></li>
</ul></li>
<li class="part"><span><b>IV HTML Widgets Visualisation</b></span></li>
<li class="chapter" data-level="5" data-path="basic-widget.html"><a href="basic-widget.html"><i class="fa fa-check"></i><b>5</b> Basic Widget</a>
<ul>
<li class="chapter" data-level="" data-path="basic-widget.html"><a href="basic-widget.html#candidate-libraries"><i class="fa fa-check"></i>Candidate Libraries</a>
<ul>
<li class="chapter" data-level="" data-path="basic-widget.html"><a href="basic-widget.html#plotly"><i class="fa fa-check"></i>Plotly</a></li>
<li class="chapter" data-level="" data-path="basic-widget.html"><a href="basic-widget.html#highchart.js"><i class="fa fa-check"></i>Highchart.js</a></li>
<li class="chapter" data-level="" data-path="basic-widget.html"><a href="basic-widget.html#chart.js"><i class="fa fa-check"></i>Chart.js</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="basic-widget.html"><a href="basic-widget.html#how-it-works"><i class="fa fa-check"></i>How it works</a></li>
<li class="chapter" data-level="" data-path="basic-widget.html"><a href="basic-widget.html#the-scaffold"><i class="fa fa-check"></i>The Scaffold</a></li>
<li class="chapter" data-level="" data-path="basic-widget.html"><a href="basic-widget.html#the-output"><i class="fa fa-check"></i>The Output</a></li>
</ul></li>
<li class="chapter" data-level="6" data-path="external-library-1.html"><a href="external-library-1.html"><i class="fa fa-check"></i><b>6</b> External Library</a>
<ul>
<li class="chapter" data-level="" data-path="external-library-1.html"><a href="external-library-1.html#dependency"><i class="fa fa-check"></i>Dependency</a></li>
<li class="chapter" data-level="" data-path="external-library-1.html"><a href="external-library-1.html#javascript-1"><i class="fa fa-check"></i>JavaScript</a></li>
<li class="chapter" data-level="" data-path="external-library-1.html"><a href="external-library-1.html#html-element"><i class="fa fa-check"></i>HTML Element</a></li>
<li class="chapter" data-level="" data-path="external-library-1.html"><a href="external-library-1.html#exercises-1"><i class="fa fa-check"></i>Exercises</a></li>
</ul></li>
<li class="chapter" data-level="7" data-path="advanced.html"><a href="advanced.html"><i class="fa fa-check"></i><b>7</b> Advanced</a>
<ul>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#dependencies-1"><i class="fa fa-check"></i>Dependencies</a></li>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#javascript-2"><i class="fa fa-check"></i>JavaScript</a></li>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#working-with-data"><i class="fa fa-check"></i>Working with Data</a></li>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#transforming-data"><i class="fa fa-check"></i>Transforming Data</a>
<ul>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#in-javascript"><i class="fa fa-check"></i>In JavaScript</a></li>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#in-r"><i class="fa fa-check"></i>In R</a></li>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#pros-cons"><i class="fa fa-check"></i>Pros &amp; Cons</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#on-print"><i class="fa fa-check"></i>On Print</a></li>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#javascript-functions"><i class="fa fa-check"></i>JavaScript Functions</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="references.html"><a href="references.html"><i class="fa fa-check"></i>References</a></li>
</ul>

      </nav>
    </div>

    <div class="book-body">
      <div class="body-inner">
        <div class="book-header" role="navigation">
          <h1>
            <i class="fa fa-circle-o-notch fa-spin"></i><a href="./">JavaScript for R</a>
          </h1>
        </div>

        <div class="page-wrapper" tabindex="-1" role="main">
          <div class="page-inner">

            <section class="normal" id="section-">
<div id="basic-widget" class="section level1" number="5">
<h1><span class="header-section-number">Chapter 5</span> Basic Widget</h1>
<p>In this chapter we cover the integration of JavaScript with R using the htmlwidgets package, which focuses on libraries that produce a visual output, it is often used for data visualisation but is not limited to it.</p>
<p>As in previous chapters we mainly learn by example, building multiple widgets of increasing complexity as we progress through the chapter. Before writing the first widget, we explore JavaScript libraries that make great candidates for htmlwidgets and attempt to understand how they work to grasp what is expected from the developer in order to integrate them with R. Finally, we build up on the previous chapter to improve how HTML widgets work with shiny.</p>
<div id="candidate-libraries" class="section level2 unnumbered" number="">
<h2>Candidate Libraries</h2>
<p>Before going down the rabbit hole it is good to take a look at the types of libraries one will work with. As htmlwidgets’ main client are JavaScript visualisation libraries let us take a look at some such popular libraries and briefly look at how they work and what they have in common. This will greatly help conceptualise what one is trying to achieve in this chapter.</p>
<div id="plotly" class="section level3 unnumbered" number="">
<h3>Plotly</h3>
<p><a href="https://plotly.com/javascript/">Plotly.js</a> is probably one of the more popular out there, it provides over 40 fully customiseable chart types, many of which are very sophisticated. This is indeed the JavaScript library used by the R package of the same name: plotly.</p>
<p>Looking at the code presented in the “Get Started” guide reveals just how convenient the library is. One must import plotly, of course, then have a <code>&lt;div&gt;</code> where to visualisation will be placed, then, using <code>Plotly.newPlot</code>, create the actual visualisation by passing it first the element previously mentioned and a JSON of options.</p>
<div class="sourceCode" id="cb160"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb160-1"><a href="basic-widget.html#cb160-1"></a><span class="dt">&lt;!DOCTYPE </span>html<span class="dt">&gt;</span></span>
<span id="cb160-2"><a href="basic-widget.html#cb160-2"></a><span class="kw">&lt;html</span><span class="ot"> xmlns=</span><span class="st">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="ot"> lang=</span><span class="st">&quot;&quot;</span><span class="ot"> xml:lang=</span><span class="st">&quot;&quot;</span><span class="kw">&gt;</span></span>
<span id="cb160-3"><a href="basic-widget.html#cb160-3"></a></span>
<span id="cb160-4"><a href="basic-widget.html#cb160-4"></a><span class="kw">&lt;head&gt;</span></span>
<span id="cb160-5"><a href="basic-widget.html#cb160-5"></a>  <span class="co">&lt;!-- Import library --&gt;</span></span>
<span id="cb160-6"><a href="basic-widget.html#cb160-6"></a>  <span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;plotly-latest.min.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb160-7"><a href="basic-widget.html#cb160-7"></a><span class="kw">&lt;/head&gt;</span></span>
<span id="cb160-8"><a href="basic-widget.html#cb160-8"></a></span>
<span id="cb160-9"><a href="basic-widget.html#cb160-9"></a><span class="kw">&lt;body&gt;</span></span>
<span id="cb160-10"><a href="basic-widget.html#cb160-10"></a>  <span class="co">&lt;!-- div to hold visualisation --&gt;</span></span>
<span id="cb160-11"><a href="basic-widget.html#cb160-11"></a>  <span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;chart&quot;</span><span class="ot"> style=</span><span class="st">&quot;width:600px;height:250px;&quot;</span><span class="kw">&gt;&lt;/div&gt;</span></span>
<span id="cb160-12"><a href="basic-widget.html#cb160-12"></a></span>
<span id="cb160-13"><a href="basic-widget.html#cb160-13"></a>  <span class="co">&lt;!-- Script to create visualsiation --&gt;</span></span>
<span id="cb160-14"><a href="basic-widget.html#cb160-14"></a>  <span class="kw">&lt;script&gt;</span></span>
<span id="cb160-15"><a href="basic-widget.html#cb160-15"></a>    el <span class="op">=</span> <span class="va">document</span>.<span class="at">getElementById</span>(<span class="st">&#39;chart&#39;</span>)<span class="op">;</span></span>
<span id="cb160-16"><a href="basic-widget.html#cb160-16"></a>    <span class="va">Plotly</span>.<span class="at">newPlot</span>(el<span class="op">,</span> [<span class="op">{</span></span>
<span id="cb160-17"><a href="basic-widget.html#cb160-17"></a>      <span class="dt">x</span><span class="op">:</span> [<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span>]<span class="op">,</span></span>
<span id="cb160-18"><a href="basic-widget.html#cb160-18"></a>      <span class="dt">y</span><span class="op">:</span> [<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">16</span>] <span class="op">}</span>]</span>
<span id="cb160-19"><a href="basic-widget.html#cb160-19"></a>    )<span class="op">;</span></span>
<span id="cb160-20"><a href="basic-widget.html#cb160-20"></a>  <span class="kw">&lt;/script&gt;</span></span>
<span id="cb160-21"><a href="basic-widget.html#cb160-21"></a><span class="kw">&lt;/body&gt;</span></span>
<span id="cb160-22"><a href="basic-widget.html#cb160-22"></a></span>
<span id="cb160-23"><a href="basic-widget.html#cb160-23"></a><span class="kw">&lt;/html&gt;</span></span></code></pre></div>
<p>Now let’s look at how another popular library does it.</p>
</div>
<div id="highchart.js" class="section level3 unnumbered" number="">
<h3>Highchart.js</h3>
<p><a href="https://www.highcharts.com/">Highcharts</a> is another library which allows creating gorgeous visualisation, maps, and more, it’s also very popular albeit not being entirely open-source.</p>
<div class="sourceCode" id="cb161"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb161-1"><a href="basic-widget.html#cb161-1"></a><span class="dt">&lt;!DOCTYPE </span>html<span class="dt">&gt;</span></span>
<span id="cb161-2"><a href="basic-widget.html#cb161-2"></a><span class="kw">&lt;html</span><span class="ot"> xmlns=</span><span class="st">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="ot"> lang=</span><span class="st">&quot;&quot;</span><span class="ot"> xml:lang=</span><span class="st">&quot;&quot;</span><span class="kw">&gt;</span></span>
<span id="cb161-3"><a href="basic-widget.html#cb161-3"></a></span>
<span id="cb161-4"><a href="basic-widget.html#cb161-4"></a><span class="kw">&lt;head&gt;</span></span>
<span id="cb161-5"><a href="basic-widget.html#cb161-5"></a>  <span class="co">&lt;!-- Import library --&gt;</span></span>
<span id="cb161-6"><a href="basic-widget.html#cb161-6"></a>  <span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;highcharts.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb161-7"><a href="basic-widget.html#cb161-7"></a><span class="kw">&lt;/head&gt;</span></span>
<span id="cb161-8"><a href="basic-widget.html#cb161-8"></a></span>
<span id="cb161-9"><a href="basic-widget.html#cb161-9"></a><span class="kw">&lt;body&gt;</span></span>
<span id="cb161-10"><a href="basic-widget.html#cb161-10"></a>  <span class="co">&lt;!-- div to hold visualisation --&gt;</span></span>
<span id="cb161-11"><a href="basic-widget.html#cb161-11"></a>  <span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;chart&quot;</span><span class="ot"> style=</span><span class="st">&quot;width:100%; height:400px;&quot;</span><span class="kw">&gt;&lt;/div&gt;</span></span>
<span id="cb161-12"><a href="basic-widget.html#cb161-12"></a></span>
<span id="cb161-13"><a href="basic-widget.html#cb161-13"></a>  <span class="co">&lt;!-- Script to create visualsiation --&gt;</span></span>
<span id="cb161-14"><a href="basic-widget.html#cb161-14"></a>  <span class="kw">&lt;script&gt;</span></span>
<span id="cb161-15"><a href="basic-widget.html#cb161-15"></a>    <span class="kw">var</span> myChart <span class="op">=</span> <span class="va">Highcharts</span>.<span class="at">chart</span>(<span class="st">&#39;chart&#39;</span><span class="op">,</span> <span class="op">{</span></span>
<span id="cb161-16"><a href="basic-widget.html#cb161-16"></a>        <span class="dt">xAxis</span><span class="op">:</span> <span class="op">{</span></span>
<span id="cb161-17"><a href="basic-widget.html#cb161-17"></a>            <span class="dt">categories</span><span class="op">:</span> [<span class="st">&#39;Apples&#39;</span><span class="op">,</span> <span class="st">&#39;Bananas&#39;</span><span class="op">,</span> <span class="st">&#39;Oranges&#39;</span>]</span>
<span id="cb161-18"><a href="basic-widget.html#cb161-18"></a>        <span class="op">},</span></span>
<span id="cb161-19"><a href="basic-widget.html#cb161-19"></a>        <span class="dt">series</span><span class="op">:</span> [<span class="op">{</span></span>
<span id="cb161-20"><a href="basic-widget.html#cb161-20"></a>            <span class="dt">name</span><span class="op">:</span> <span class="st">&#39;Jane&#39;</span><span class="op">,</span></span>
<span id="cb161-21"><a href="basic-widget.html#cb161-21"></a>            <span class="dt">data</span><span class="op">:</span> [<span class="dv">1</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">4</span>]</span>
<span id="cb161-22"><a href="basic-widget.html#cb161-22"></a>        <span class="op">},</span> <span class="op">{</span></span>
<span id="cb161-23"><a href="basic-widget.html#cb161-23"></a>            <span class="dt">name</span><span class="op">:</span> <span class="st">&#39;John&#39;</span><span class="op">,</span></span>
<span id="cb161-24"><a href="basic-widget.html#cb161-24"></a>            <span class="dt">data</span><span class="op">:</span> [<span class="dv">5</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">3</span>]</span>
<span id="cb161-25"><a href="basic-widget.html#cb161-25"></a>        <span class="op">}</span>]</span>
<span id="cb161-26"><a href="basic-widget.html#cb161-26"></a>    <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb161-27"><a href="basic-widget.html#cb161-27"></a>  <span class="kw">&lt;/script&gt;</span></span>
<span id="cb161-28"><a href="basic-widget.html#cb161-28"></a><span class="kw">&lt;/body&gt;</span></span>
<span id="cb161-29"><a href="basic-widget.html#cb161-29"></a></span>
<span id="cb161-30"><a href="basic-widget.html#cb161-30"></a><span class="kw">&lt;/html&gt;</span></span></code></pre></div>
<p>The above is very similar to what plotly.js requires: import libraries, create a <code>&lt;div&gt;</code> where to put the visualisation, and, to create the chart, run a function which also takes the id of the div where to place the chart and a JSON of options defining the actual chart, including the data.</p>
</div>
<div id="chart.js" class="section level3 unnumbered" number="">
<h3>Chart.js</h3>
<p><a href="https://www.chartjs.org/">Chart.js</a> is yet another library which to draw standard charts popular for its permissive license and convenient API.</p>
<div class="sourceCode" id="cb162"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb162-1"><a href="basic-widget.html#cb162-1"></a><span class="dt">&lt;!DOCTYPE </span>html<span class="dt">&gt;</span></span>
<span id="cb162-2"><a href="basic-widget.html#cb162-2"></a><span class="kw">&lt;html</span><span class="ot"> xmlns=</span><span class="st">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="ot"> lang=</span><span class="st">&quot;&quot;</span><span class="ot"> xml:lang=</span><span class="st">&quot;&quot;</span><span class="kw">&gt;</span></span>
<span id="cb162-3"><a href="basic-widget.html#cb162-3"></a></span>
<span id="cb162-4"><a href="basic-widget.html#cb162-4"></a><span class="kw">&lt;head&gt;</span></span>
<span id="cb162-5"><a href="basic-widget.html#cb162-5"></a>  <span class="co">&lt;!-- Import library --&gt;</span></span>
<span id="cb162-6"><a href="basic-widget.html#cb162-6"></a>  <span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;Chart.min.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb162-7"><a href="basic-widget.html#cb162-7"></a><span class="kw">&lt;/head&gt;</span></span>
<span id="cb162-8"><a href="basic-widget.html#cb162-8"></a></span>
<span id="cb162-9"><a href="basic-widget.html#cb162-9"></a><span class="kw">&lt;body&gt;</span></span>
<span id="cb162-10"><a href="basic-widget.html#cb162-10"></a>  <span class="co">&lt;!-- canvas to hold visualisation --&gt;</span></span>
<span id="cb162-11"><a href="basic-widget.html#cb162-11"></a>  <span class="kw">&lt;canvas</span><span class="ot"> id=</span><span class="st">&quot;chart&quot;</span><span class="ot"> width=</span><span class="st">&quot;400&quot;</span><span class="ot"> height=</span><span class="st">&quot;400&quot;</span><span class="kw">&gt;&lt;/canvas&gt;</span></span>
<span id="cb162-12"><a href="basic-widget.html#cb162-12"></a></span>
<span id="cb162-13"><a href="basic-widget.html#cb162-13"></a>  <span class="co">&lt;!-- Script to create visualsiation --&gt;</span></span>
<span id="cb162-14"><a href="basic-widget.html#cb162-14"></a>  <span class="kw">&lt;script&gt;</span></span>
<span id="cb162-15"><a href="basic-widget.html#cb162-15"></a>    <span class="kw">var</span> el <span class="op">=</span> <span class="va">document</span>.<span class="at">getElementById</span>(<span class="st">&#39;chart&#39;</span>).<span class="at">getContext</span>(<span class="st">&#39;2d&#39;</span>)<span class="op">;</span>    </span>
<span id="cb162-16"><a href="basic-widget.html#cb162-16"></a>    <span class="kw">var</span> myChart <span class="op">=</span> <span class="kw">new</span> <span class="at">Chart</span>(el<span class="op">,</span> <span class="op">{</span></span>
<span id="cb162-17"><a href="basic-widget.html#cb162-17"></a>      <span class="dt">type</span><span class="op">:</span> <span class="st">&#39;bar&#39;</span><span class="op">,</span></span>
<span id="cb162-18"><a href="basic-widget.html#cb162-18"></a>      <span class="dt">data</span><span class="op">:</span> <span class="op">{</span></span>
<span id="cb162-19"><a href="basic-widget.html#cb162-19"></a>        <span class="dt">labels</span><span class="op">:</span> [<span class="st">&#39;Red&#39;</span><span class="op">,</span> <span class="st">&#39;Blue&#39;</span><span class="op">,</span> <span class="st">&#39;Yellow&#39;</span><span class="op">,</span> <span class="st">&#39;Green&#39;</span><span class="op">,</span> <span class="st">&#39;Purple&#39;</span><span class="op">,</span> <span class="st">&#39;Orange&#39;</span>]<span class="op">,</span></span>
<span id="cb162-20"><a href="basic-widget.html#cb162-20"></a>        <span class="dt">datasets</span><span class="op">:</span> [<span class="op">{</span></span>
<span id="cb162-21"><a href="basic-widget.html#cb162-21"></a>          <span class="dt">label</span><span class="op">:</span> <span class="st">&#39;# of Votes&#39;</span><span class="op">,</span></span>
<span id="cb162-22"><a href="basic-widget.html#cb162-22"></a>          <span class="dt">data</span><span class="op">:</span> [<span class="dv">12</span><span class="op">,</span> <span class="dv">19</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span>]</span>
<span id="cb162-23"><a href="basic-widget.html#cb162-23"></a>        <span class="op">}</span>]</span>
<span id="cb162-24"><a href="basic-widget.html#cb162-24"></a>      <span class="op">}</span></span>
<span id="cb162-25"><a href="basic-widget.html#cb162-25"></a>    <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb162-26"><a href="basic-widget.html#cb162-26"></a>  <span class="kw">&lt;/script&gt;</span></span>
<span id="cb162-27"><a href="basic-widget.html#cb162-27"></a><span class="kw">&lt;/body&gt;</span></span>
<span id="cb162-28"><a href="basic-widget.html#cb162-28"></a></span>
<span id="cb162-29"><a href="basic-widget.html#cb162-29"></a><span class="kw">&lt;/html&gt;</span></span></code></pre></div>
<p>We again observe a very similar structure as with previous libraries. The library is imported, instead of a <code>div</code> chart.js uses a <code>canvas</code>, and the visualisation is also created from a single function which takes the canvas as first argument and a JSON of options as second.</p>
<p>Hopefully this reveals the repeating structure such libraries tend to follow and also hints at should be reproduced, to some extent at least, using R.</p>
</div>
</div>
<div id="how-it-works" class="section level2 unnumbered" number="">
<h2>How it works</h2>
<p>Imagine there is no such package as HTML widgets to help create interactive visualisations from R: how would one attempt to go about it?</p>
<p>An interactive visualisation using JavaScript will will be contained within an HTML document, therefore it would probably have to be created first. Secondly, the visualisation that is yet to be created likely relies on external libraries, these would need to be imported in the document. The document should also include an HTML element (e.g.: <code>&lt;div&gt;</code>) to host said visualisation. Then data would have to be serialised in R and embedded into the document where it should be read by JavaScript code that uses it to create the visualisation. Finally all should be managed to work seamlessly across R markdown, shiny, and other settings.</p>
<p>Thankfully the htmlwidgets package is there to handle most of this. Nonetheless, it is important to understand that these operations are undertaken (to some degree) by htmlwidgets as it greatly helps use the package.</p>
<p>Must remember when building HTML widgets:</p>
<ul>
<li>Import dependencies</li>
<li>Create an html element to hold visualisation</li>
<li>Serialise R data to JSON</li>
<li>Handle JSON data to produce visualisation</li>
</ul>
</div>
<div id="the-scaffold" class="section level2 unnumbered" number="">
<h2>The Scaffold</h2>
<p>With some vague understanding of how such widgets work internally one is ready to “scaffold” one with the aim of rummaging through its components to grasp a greater understanding of how such interactive outputs are actually produced. The way one sets up such a package is stunningly simple. Below we create a package named “playground” which will be used to mess around and explore. Though one could probably create widgets outside of an R package, it would only make things more complicated.</p>
<div class="sourceCode" id="cb163"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb163-1"><a href="basic-widget.html#cb163-1"></a><span class="kw">create_package</span>(<span class="st">&quot;playground&quot;</span>)</span></code></pre></div>
<p>Then, from the root of the package created, we scaffold a widget which we call “play”.</p>
<div class="sourceCode" id="cb164"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb164-1"><a href="basic-widget.html#cb164-1"></a>htmlwidgets<span class="op">::</span><span class="kw">scaffoldWidget</span>(<span class="st">&quot;play&quot;</span>)</span></code></pre></div>
<p>This function puts together the minimalistic structure necessary to implement an HTML widget and opens <code>play.R</code>, <code>play.js</code> and <code>play.yaml</code> in the RStudio IDE or the default text editor. These files are named after the widget and will form the core of the package. The R file contains core functions of the R API, namely the <code>play</code> function which creates the widget itself, and the <code>render*</code> and <code>*output</code> functions that handle the widget in the shiny server and UI respectively. The <code>.js</code> file contains JavaScript functions that actually generate the visual output.</p>
<div class="sourceCode" id="cb165"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb165-1"><a href="basic-widget.html#cb165-1"></a>devtools<span class="op">::</span><span class="kw">document</span>()</span>
<span id="cb165-2"><a href="basic-widget.html#cb165-2"></a>devtools<span class="op">::</span><span class="kw">load_all</span>()</span></code></pre></div>
<p>It might be hard to believe, but at this stage one already has a fully functioning widget ready to use after documenting, and building the package. Indeed, the <code>play.R</code> file that that was created contains a function named “play” ẁhich takes, amongst other arguments, a message.</p>
<div class="sourceCode" id="cb166"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb166-1"><a href="basic-widget.html#cb166-1"></a><span class="kw">play</span>(<span class="dt">message =</span> <span class="st">&quot;This is a widget!&quot;</span>)</span></code></pre></div>
<div class="figure">
<img src="images/playground-1.png" alt="" />
<p class="caption">First HTML widget</p>
</div>
<p>This displays the message in the RStudio “Viewer,” or the your default browser which indicates that the function does indeed create an HTML output. One can use the the <img src="images/open-in-browser.png" /> button located in the top right of the RStudio “Viewer” to open the message in web browser which can prove very useful to look under the hood of the widgets for debugging.</p>
</div>
<div id="the-output" class="section level2 unnumbered" number="">
<h2>The Output</h2>
<p>With an out-of-the-box HTML widget package one can start exploring the internals to understand how it works. Let’s start by retracing the path taken by the message written in R to its seemingly magical appearance in HTML. The <code>play</code> function previously used, takes the <code>message</code> wraps it into a list which is then used in <code>htmlwidgets::createWidget</code>.</p>
<div class="sourceCode" id="cb167"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb167-1"><a href="basic-widget.html#cb167-1"></a><span class="co"># forward options using x</span></span>
<span id="cb167-2"><a href="basic-widget.html#cb167-2"></a>x =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb167-3"><a href="basic-widget.html#cb167-3"></a>  <span class="dt">message =</span> message</span>
<span id="cb167-4"><a href="basic-widget.html#cb167-4"></a>)</span></code></pre></div>
<p>Wrapping a string in a list might seem unnecessary but one will eventually add variables when building a more complex widget, starting with a list makes it easier to add them later on.</p>
<p>To investigate the widget we should look under the hood; the source code of the created (and rendered) output can be accessed in different ways, 1) by right-clicking on the message displayed in the RStudio Viewer and selecting “Inspect element,” or 2) by opening the visualisation in your browser using the <img src="images/open-in-browser.png" /> button located in the top right of the “Viewer,” and in the browser right clicking on the message to select “Inspect.” The latter is advised as web browsers such as Chrome or Firefox provide much friendlier interfaces for such functionalities as well as shortcuts to inspect or view the source code of a page.</p>
<p>Below is a part of the <code>&lt;body&gt;</code> of the output of <code>play("This is a widget!")</code> obtained with the method described in the previous paragraph.</p>
<div class="sourceCode" id="cb168"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb168-1"><a href="basic-widget.html#cb168-1"></a><span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;htmlwidget_container&quot;</span><span class="kw">&gt;</span></span>
<span id="cb168-2"><a href="basic-widget.html#cb168-2"></a>  <span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;htmlwidget-c21cca0e76e520b46fc7&quot;</span><span class="ot"> style=</span><span class="st">&quot;width:960px;height:500px;&quot;</span><span class="ot"> class=</span><span class="st">&quot;play html-widget&quot;</span><span class="kw">&gt;</span>This is a widget!<span class="kw">&lt;/div&gt;</span></span>
<span id="cb168-3"><a href="basic-widget.html#cb168-3"></a><span class="kw">&lt;/div&gt;</span></span>
<span id="cb168-4"><a href="basic-widget.html#cb168-4"></a><span class="kw">&lt;script</span><span class="ot"> type=</span><span class="st">&quot;application/json&quot;</span><span class="ot"> data-for=</span><span class="st">&quot;htmlwidget-c21cca0e76e520b46fc7&quot;</span><span class="kw">&gt;</span><span class="op">{</span><span class="st">&quot;x&quot;</span><span class="op">:{</span><span class="st">&quot;message&quot;</span><span class="op">:</span><span class="st">&quot;This is a widget!&quot;</span><span class="op">},</span><span class="st">&quot;evals&quot;</span><span class="op">:</span>[]<span class="op">,</span><span class="st">&quot;jsHooks&quot;</span><span class="op">:</span>[]<span class="op">}</span><span class="kw">&lt;/script&gt;</span></span></code></pre></div>
<p>One thing the source code of the rendered output reveals is the element (<code>div</code>) created by the htmlwidgets package to hold the message (the class name is identical to that of the widget, <code>play</code>), as well as, below it, in the <code>&lt;script&gt;</code> tag, the JSON object which includes the <code>x</code> variable used in the <code>play</code> function. The <code>div</code> created bears a randomly generated <code>id</code> which one can define when creating the widget using the <code>elementId</code> argument.</p>
<div class="sourceCode" id="cb169"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb169-1"><a href="basic-widget.html#cb169-1"></a><span class="co"># specify the id</span></span>
<span id="cb169-2"><a href="basic-widget.html#cb169-2"></a><span class="kw">play</span>(<span class="st">&quot;This is another widget&quot;</span>, <span class="dt">elementId =</span> <span class="st">&quot;myViz&quot;</span>)</span></code></pre></div>
<div class="sourceCode" id="cb170"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb170-1"><a href="basic-widget.html#cb170-1"></a><span class="co">&lt;!-- div bears id specified in R --&gt;</span></span>
<span id="cb170-2"><a href="basic-widget.html#cb170-2"></a><span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;myViz&quot;</span><span class="ot"> style=</span><span class="st">&quot;width:960px;height:500px;&quot;</span><span class="ot"> class=</span><span class="st">&quot;play html-widget&quot;</span><span class="kw">&gt;</span>This is another widget<span class="kw">&lt;/div&gt;</span></span></code></pre></div>
<p>You will also notice that this affects the <code>script</code> tag below it, the <code>data-for</code> attribute of which is also set to “myViz,” this indicates that it is used to tie the JSON data to a <code>div</code>, essential for htmlwidgets to manage multiple visualisation in R markdown or Shiny for instance. Then again, this happens in the background without the developer (you) having to worry about it.</p>
<div class="sourceCode" id="cb171"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb171-1"><a href="basic-widget.html#cb171-1"></a><span class="kw">&lt;script</span><span class="ot"> type=</span><span class="st">&quot;application/json&quot;</span><span class="ot"> data-for=</span><span class="st">&quot;myViz&quot;</span><span class="kw">&gt;</span><span class="op">{</span><span class="st">&quot;x&quot;</span><span class="op">:{</span><span class="st">&quot;message&quot;</span><span class="op">:</span><span class="st">&quot;This is a widget!&quot;</span><span class="op">},</span><span class="st">&quot;evals&quot;</span><span class="op">:</span>[]<span class="op">,</span><span class="st">&quot;jsHooks&quot;</span><span class="op">:</span>[]<span class="op">}</span><span class="kw">&lt;/script&gt;</span></span></code></pre></div>
<p>Inspecting the output also shows the dependencies imported, these are placed within the <code>head</code> HTML tags at the top of the page.</p>
<div class="sourceCode" id="cb172"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb172-1"><a href="basic-widget.html#cb172-1"></a><span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;lib/htmlwidgets-1.5.1/htmlwidgets.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb172-2"><a href="basic-widget.html#cb172-2"></a><span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;lib/play-binding-0.0.0.9000/play.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span></code></pre></div>
<p>This effectively imports the <code>htmlwidgets.js</code> library as well as the <code>play.js</code> file, and were the visualisation depending on external libraries they would appear alongside those. Peaking inside the <code>play.js</code> file located at <code>inst/htmlwidgets/play.js</code> reveals the code below we see:</p>
<div class="sourceCode" id="cb173"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb173-1"><a href="basic-widget.html#cb173-1"></a><span class="co">// play.js</span></span>
<span id="cb173-2"><a href="basic-widget.html#cb173-2"></a><span class="va">HTMLWidgets</span>.<span class="at">widget</span>(<span class="op">{</span></span>
<span id="cb173-3"><a href="basic-widget.html#cb173-3"></a></span>
<span id="cb173-4"><a href="basic-widget.html#cb173-4"></a>  <span class="dt">name</span><span class="op">:</span> <span class="st">&#39;play&#39;</span><span class="op">,</span></span>
<span id="cb173-5"><a href="basic-widget.html#cb173-5"></a></span>
<span id="cb173-6"><a href="basic-widget.html#cb173-6"></a>  <span class="dt">type</span><span class="op">:</span> <span class="st">&#39;output&#39;</span><span class="op">,</span></span>
<span id="cb173-7"><a href="basic-widget.html#cb173-7"></a></span>
<span id="cb173-8"><a href="basic-widget.html#cb173-8"></a>  <span class="dt">factory</span><span class="op">:</span> <span class="kw">function</span>(el<span class="op">,</span> width<span class="op">,</span> height) <span class="op">{</span></span>
<span id="cb173-9"><a href="basic-widget.html#cb173-9"></a></span>
<span id="cb173-10"><a href="basic-widget.html#cb173-10"></a>    <span class="co">// </span><span class="al">TODO</span><span class="co">: define shared variables for this instance</span></span>
<span id="cb173-11"><a href="basic-widget.html#cb173-11"></a></span>
<span id="cb173-12"><a href="basic-widget.html#cb173-12"></a>    <span class="cf">return</span> <span class="op">{</span></span>
<span id="cb173-13"><a href="basic-widget.html#cb173-13"></a></span>
<span id="cb173-14"><a href="basic-widget.html#cb173-14"></a>      <span class="dt">renderValue</span><span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb173-15"><a href="basic-widget.html#cb173-15"></a></span>
<span id="cb173-16"><a href="basic-widget.html#cb173-16"></a>        <span class="co">// </span><span class="al">TODO</span><span class="co">: code to render the widget, e.g.</span></span>
<span id="cb173-17"><a href="basic-widget.html#cb173-17"></a>        <span class="va">el</span>.<span class="at">innerText</span> <span class="op">=</span> <span class="va">x</span>.<span class="at">message</span><span class="op">;</span></span>
<span id="cb173-18"><a href="basic-widget.html#cb173-18"></a></span>
<span id="cb173-19"><a href="basic-widget.html#cb173-19"></a>      <span class="op">},</span></span>
<span id="cb173-20"><a href="basic-widget.html#cb173-20"></a></span>
<span id="cb173-21"><a href="basic-widget.html#cb173-21"></a>      <span class="dt">resize</span><span class="op">:</span> <span class="kw">function</span>(width<span class="op">,</span> height) <span class="op">{</span></span>
<span id="cb173-22"><a href="basic-widget.html#cb173-22"></a></span>
<span id="cb173-23"><a href="basic-widget.html#cb173-23"></a>        <span class="co">// </span><span class="al">TODO</span><span class="co">: code to re-render the widget with a new size</span></span>
<span id="cb173-24"><a href="basic-widget.html#cb173-24"></a></span>
<span id="cb173-25"><a href="basic-widget.html#cb173-25"></a>      <span class="op">}</span></span>
<span id="cb173-26"><a href="basic-widget.html#cb173-26"></a></span>
<span id="cb173-27"><a href="basic-widget.html#cb173-27"></a>    <span class="op">};</span></span>
<span id="cb173-28"><a href="basic-widget.html#cb173-28"></a>  <span class="op">}</span></span>
<span id="cb173-29"><a href="basic-widget.html#cb173-29"></a><span class="op">}</span>)<span class="op">;</span></span></code></pre></div>
<p>However convoluted this may appear at first do not let that intimate you. The <code>factory</code> function returns two functions, one of which, <code>resize</code>, is currently empty, let’s therefore look at the other one first, <code>renderValue</code>: the function that in fact renders the visualisation. It takes an object <code>x</code> from which is accesses the “message” variable that it uses as text for object <code>el</code> (<code>el.innerText</code>). The object <code>x</code> passed to this function is actually the list of the same name that was build in the R function <code>play</code>! While in R one would access the <code>message</code> in list <code>x</code> with <code>x$message</code> in JavaScript to access the <code>message</code> in the JSON <code>x</code> one writes <code>x.message</code>, only changing the dollar sign to a dot. Let’s show this perhaps more clearly by printing the content of <code>x</code>.</p>
<div class="sourceCode" id="cb174"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb174-1"><a href="basic-widget.html#cb174-1"></a><span class="va">console</span>.<span class="at">log</span>(x)<span class="op">;</span></span>
<span id="cb174-2"><a href="basic-widget.html#cb174-2"></a><span class="va">el</span>.<span class="at">innerText</span> <span class="op">=</span> <span class="va">x</span>.<span class="at">message</span><span class="op">;</span></span></code></pre></div>
<p>We place <code>console.log</code> to print the content of <code>x</code> in the console, reload the package with <code>devtools::load_all</code> and use the function <code>play</code> again then explore the console from the browser (inspect and go to the “console” tab).</p>
<div class="figure">
<img src="images/playground-console-x.png" alt="" />
<p class="caption">Console tab output</p>
</div>
<p>This displays the JSON object containing the message: it looks eerily similar to the list that was created in R (<code>x = list(message = "This is a widget!")</code>). What one should take away from this is that data that needs to be communicated from R to the JavaScript function should be placed in the R list <code>x</code>. This list is serialised to JSON and placed in the HTML output in a <code>script</code> tag with a <code>data-for</code> attribute. This attribute indicates which widget the data is destined for. This effectively enables htmlwidgets to match the serialised data with the output elements: data in <code>&lt;script data-for='viz'&gt;</code> is to be used to create a visualisation in <code>&lt;div id='viz'&gt;</code>.</p>
<p>Before we move on to other things one should also grasp a better understanding of the <code>el</code> object, which can also be logged in the console.</p>
<div class="sourceCode" id="cb175"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb175-1"><a href="basic-widget.html#cb175-1"></a><span class="va">console</span>.<span class="at">log</span>(x)<span class="op">;</span></span>
<span id="cb175-2"><a href="basic-widget.html#cb175-2"></a><span class="va">console</span>.<span class="at">log</span>(el)<span class="op">;</span></span>
<span id="cb175-3"><a href="basic-widget.html#cb175-3"></a><span class="va">el</span>.<span class="at">innerText</span> <span class="op">=</span> <span class="va">x</span>.<span class="at">message</span><span class="op">;</span></span></code></pre></div>
<div class="figure">
<img src="images/playground-console-el.png" alt="" />
<p class="caption">Console tab output</p>
</div>
<p>This displays the HTML element created by htmlwidgets that is meant to hold the visualisation, or in this case, the message. If you are familiar with JavaScript, this is the element that would be returned by <code>document.getElementById</code>. This object allows manipulating the element in pretty much any way imaginable, change its position, its colour, its size, or, as done here, to insert some text in its place. What’s more one can access attributes of the object just like a JSON array. Therefore one can log the <code>id</code> of the element.</p>
<div class="sourceCode" id="cb176"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb176-1"><a href="basic-widget.html#cb176-1"></a><span class="co">// print the id of the element</span></span>
<span id="cb176-2"><a href="basic-widget.html#cb176-2"></a><span class="va">console</span>.<span class="at">log</span>(<span class="va">el</span>.<span class="at">id</span>)<span class="op">;</span></span>
<span id="cb176-3"><a href="basic-widget.html#cb176-3"></a><span class="va">el</span>.<span class="at">innerText</span> <span class="op">=</span> <span class="va">x</span>.<span class="at">message</span><span class="op">;</span></span></code></pre></div>
<p>Making the modifications above and reloading the package, one can create a widget given a specific id and see it displayed in the console, e.g.: <code>play("hello", elementId = "see-you-in-the-console")</code>.</p>
<p>In an attempt to become more at ease with this setup let us change something and play with the widget. Out-of-the-box htmlwidgets uses <code>innerText</code>, which does very much what it says on the tin, it places text inside an element. JavaScript comes with another function akin to <code>innerText</code>, <code>innerHTML</code>. While the former only allows inserting text the former lets one insert any HTML.</p>
<div class="sourceCode" id="cb177"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb177-1"><a href="basic-widget.html#cb177-1"></a><span class="va">el</span>.<span class="at">innerHTML</span> <span class="op">=</span> <span class="va">x</span>.<span class="at">message</span><span class="op">;</span></span></code></pre></div>
<p>After changing the <code>play.js</code> file as above, and re-loading the package, one can use arbitrary HTML as messages.</p>
<div class="sourceCode" id="cb178"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb178-1"><a href="basic-widget.html#cb178-1"></a><span class="kw">play</span>(<span class="st">&quot;&lt;h1&gt;Using HTML!&lt;/h1&gt;&quot;</span>)</span></code></pre></div>
<div class="figure">
<img src="images/playground-h1.png" alt="" />
<p class="caption">Widget output</p>
</div>
<p>That makes for a great improvement which opens the door to many possibilities. However, the interface this provides is unintuitive. Albeit similar, R users are more familiar with shiny and htmltools <span class="citation">(RStudio and Inc. <a href="#ref-R-htmltools" role="doc-biblioref">2019</a>)</span> tags than HTML tags, e.g.: <code>&lt;h1&gt;&lt;/h1&gt;</code> translates to <code>h1()</code> in R. The package should allow users to use those instead of forcing them to collapse HTML content in a string. Fortunately, there is a very easy way to obtain the HTML from those functions: convert it to a character string.</p>
<div class="sourceCode" id="cb179"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb179-1"><a href="basic-widget.html#cb179-1"></a>html &lt;-<span class="st"> </span>shiny<span class="op">::</span><span class="kw">h1</span>(<span class="st">&quot;HTML tag&quot;</span>)</span>
<span id="cb179-2"><a href="basic-widget.html#cb179-2"></a></span>
<span id="cb179-3"><a href="basic-widget.html#cb179-3"></a><span class="kw">class</span>(html)</span></code></pre></div>
<pre><code>## [1] &quot;shiny.tag&quot;</code></pre>
<div class="sourceCode" id="cb181"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb181-1"><a href="basic-widget.html#cb181-1"></a><span class="co"># returns string</span></span>
<span id="cb181-2"><a href="basic-widget.html#cb181-2"></a><span class="kw">as.character</span>(html)</span></code></pre></div>
<pre><code>## [1] &quot;&lt;h1&gt;HTML tag&lt;/h1&gt;&quot;</code></pre>
<p>Implementing this in the <code>play</code> function will look like this.</p>
<div class="sourceCode" id="cb183"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb183-1"><a href="basic-widget.html#cb183-1"></a><span class="co"># forward options using x</span></span>
<span id="cb183-2"><a href="basic-widget.html#cb183-2"></a>x =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb183-3"><a href="basic-widget.html#cb183-3"></a>  <span class="dt">message =</span> <span class="kw">as.character</span>(message)</span>
<span id="cb183-4"><a href="basic-widget.html#cb183-4"></a>)</span></code></pre></div>
<p>Reloading the package with <code>devtools::load_all</code> lets one use shiny tags as the message.</p>
<div class="sourceCode" id="cb184"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb184-1"><a href="basic-widget.html#cb184-1"></a><span class="kw">play</span>(shiny<span class="op">::</span><span class="kw">h2</span>(<span class="st">&quot;Chocolate is a colour&quot;</span>, <span class="dt">style =</span> <span class="st">&quot;color:chocolate;&quot;</span>))</span></code></pre></div>
<div class="figure">
<img src="images/playground-color.png" alt="" />
<p class="caption">Using shiny tags</p>
</div>
<p>This hopefully provides some understanding of how htmlwidgets work internally and thereby helps building such packages. To recapitulate, an HTML document is created in which div is placed and given a certain id, this id is also used in a script tag that contains JSON data passed from R so that a JavaScript function we define can read that data in and use it to generate a visual output in a div. However, as much as this section covered, the topic of JavaScript dependencies was not touched, this is approached in the following section where we build another, more interesting widget, which uses an external dependency.</p>

</div>
</div>
<h3>References</h3>
<div id="refs" class="references">
<div id="ref-R-htmltools">
<p>RStudio, and Inc. 2019. <em>Htmltools: Tools for Html</em>. <a href="https://CRAN.R-project.org/package=htmltools">https://CRAN.R-project.org/package=htmltools</a>.</p>
</div>
</div>
            </section>

          </div>
        </div>
      </div>
<a href="a-two-way-street.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="external-library-1.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
    </div>
  </div>
<script src="libs/gitbook/js/app.min.js"></script>
<script src="libs/gitbook/js/lunr.js"></script>
<script src="libs/gitbook/js/clipboard.min.js"></script>
<script src="libs/gitbook/js/plugin-search.js"></script>
<script src="libs/gitbook/js/plugin-sharing.js"></script>
<script src="libs/gitbook/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook/js/plugin-bookdown.js"></script>
<script src="libs/gitbook/js/jquery.highlight.js"></script>
<script src="libs/gitbook/js/plugin-clipboard.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"all": {}
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/JohnCoene/r-and-javascript/edit/master/05-htmlwidgets.Rmd",
"text": "Edit"
},
"history": {
"link": null,
"text": null
},
"view": {
"link": null,
"text": null
},
"download": {},
"toc": {
"collapse": "section"
}
});
});
</script>

</body>

</html>
